package com.apestech.framework.sql.condition;

import com.apestech.framework.sql.MultiDataBase;
import com.apestech.framework.xml.sql.SqlNodeVar;
import com.apestech.framework.stream.ArrayObject;

import java.util.ArrayList;

public class QueryExpression {
	private String fieldName;
    private Object value;
    private String operator;
    private String alias;
    private String sql="";
    private String dbType="ORACLE";
    private Object resultValue=null;
    private ArrayObject list;
    private MultiDataBase db;
    private String tree;
    private String idField;
    private String parentField;
	private String varfield;
    
    public QueryExpression(String fieldName, Object value, String operator){
    	this.alias="";
    	this.fieldName=fieldName;
    	this.value=value;
    	this.operator=operator;
    	db=new MultiDataBase(this.dbType);
    	iniAlias();
    }

    public QueryExpression(String fieldName, Object value, String operator, String alias){
    	this.alias=alias;
    	this.fieldName=fieldName;
    	this.value=value;
    	this.operator=operator;
    	this.db=new MultiDataBase(this.dbType);
    	iniAlias();
    }
    
    public QueryExpression(String fieldName, Object value, String operator, String alias, String dbType){
    	this.dbType=dbType;
    	this.alias=alias;
    	this.fieldName=fieldName;
    	this.value=value;
    	this.operator=operator;
    	this.db=new MultiDataBase(this.dbType);
    	iniAlias();
    }

    public void setTree(String tree, String idField, String parentField){
    	this.tree=tree;
    	this.idField=idField;
    	this.parentField=parentField;
	}
    
    public void setDbType(String dbType){
    	this.dbType=dbType;
    }
    
    private void iniAlias(){
    	if(this.alias==null){
    		this.alias="";
    	}
    	if(!"".equals(this.alias)){
    		this.alias=this.alias+".";
    	}
		if(fieldName.indexOf(".")>=0){
			String[] list=fieldName.split("\\.");
			varfield=fieldName;
			fieldName=list[list.length-1];
		} else varfield=fieldName;
    }
    
    public String getSql(){
    	return this.sql;
    }
    
    public Object getValue(){
    	return this.resultValue;
    }
    
    public void getCondition() throws Exception{
    	switch (operator.toUpperCase()) {
	    	case "EQ":
	            sql=alias+fieldName+" = "+"#{"+varfield+"}";
	            resultValue=value;
	            break;
	        case "NE":
	        	sql=alias+fieldName+" <> "+"#{"+varfield+"}";
	        	resultValue=value;
	            break;
	        case "LIKE":
	        	sql=alias+fieldName+" like "+ db.getStringConcat("'%'","#{"+varfield+"}","'%'");
	        	resultValue=value;
	            break;
	        case "LLIKE":
	        	sql=alias+fieldName+" like "+ db.getStringConcat("#{"+varfield+"}","'%'");
	        	resultValue=value;
	            break;
	        case "RLIKE":
	        	sql=alias+fieldName+" like "+ db.getStringConcat("'%'","#{"+varfield+"}");
	        	resultValue=value;
	            break;
	        case "OLIKE":  //反向LIKE   '01010101' like FLID||'%'
	        	sql="#{"+fieldName+"} like "+db.getStringConcat(alias+varfield,"'%'");
	        	resultValue=value;
	            break;
	        case "LT":
	        	sql=alias+fieldName+" < "+"#{"+varfield+"}";
	        	resultValue=value;
	            break;
	        case "GT":
	        	sql=alias+fieldName+" > "+"#{"+varfield+"}";
	        	resultValue=value;
	            break;
	        case "LTE":
	        	sql=alias+fieldName+" <= "+"#{"+varfield+"}";
	        	resultValue=value;
	            break;
	        case "GTE":
	        	sql=alias+fieldName+" >= "+"#{"+varfield+"}";
	        	resultValue=value;
	            break;
	        case "IS_NULL":
	        	sql=alias+fieldName+" is null ";
	            break;
	        case "IS_NOT_NULL":
	        	sql=alias+fieldName+" is not null ";
	            break;
	        case "IN":
				getInStr(value, "in");
	            break;
	        case "NIN":
				getInStr(value, "not in");
	            break;
	        case "PARENT":
				getTreeSql(false);
	            break;
			case "TREE":
				getTreeSql(true);
				break;
    	}
    }

    private void getTreeSql(boolean child) throws Exception {
    	if(child) sql=db.getTreeChild(tree, idField, parentField, fieldName, alias, value);
    	else sql=db.getTreeParent(tree, idField, parentField, fieldName, alias, value);
		if(sql!=null && !"".equals(sql)){
			//sql=" EXISTS ("+sql+")";
		}
	}
    
    private void getInStr(Object value, String express) throws Exception{
    	boolean flag=false;
		if(!(value instanceof ArrayList)){
			ArrayList l=new ArrayList();
			l.add(value);
			value=l;
			flag=true;
		}
		list=new ArrayObject(value);
		if(list.size()>0){
			sql=alias+fieldName+" "+express+" (";

			String s="";
			int i=0;
			while(list.next()){
				if(!"".equals(s)){
					s=s+",";
				}
				if(flag) s=s+"'"+list.getText()+"'";
				else s=s+"${"+this.fieldName+ SqlNodeVar.getLISTVAR()+i+"}";
				i++;
			}
			sql=sql+s;
			sql=sql+")";
		}
    }

}
